package acme.ws;

import java.io.IOException;
import java.util.Collection;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import acme.db.CrudDao;
import acme.entity.DailyDeal;
import acme.entity.Entity;
import acme.entity.Product;

public abstract class EntityServlet<T extends Entity> extends JSONServlet {
	
	private static final long serialVersionUID = 8893392317087332094L;

	protected abstract CrudDao<T> getDAO();
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse response)
			throws ServletException, IOException {
		String path = req.getPathInfo();
		String itemId = req.getParameter("itemId");
		String method = req.getParameter("method");

		CrudDao<T> dao = getDAO();
		/**
		 * This first if statement is a complete workaround and is out of place given this code structure. 
		 * if this code is refactored, this block should be removed and done properly.  
		 */
		if("dailyDeal".equalsIgnoreCase(method)){
			Product product = DailyDealServlet.getRandomProduct();
			DailyDeal dailyDeal = DailyDealServlet.getDailyDeal(product);
			this.returnJSON(dailyDeal, response);
		}
		else if(itemId != null){
			T product = dao.readResource(itemId);
			if(product != null) returnJSON(product, response);
			else returnJSON("{\"Item Not Found\"}", response);
		}
		else if(path == null || path.indexOf('/') == -1 || path.length() == 1){
			Collection<T> entities = dao.getAllResources();
			returnJSON(entities, response);
		}else{
			String id = path.substring(path.indexOf('/') + 1);
			T product = dao.readResource(id);
			returnJSON(product, response);
		}
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.createOrUpdate(req, resp, false);
	}

	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.createOrUpdate(req, resp, true);
	}
	
	private void createOrUpdate(HttpServletRequest req, HttpServletResponse resp, boolean update)
			throws ServletException, IOException {
		String path = req.getPathInfo();
		String id = path.substring(path.indexOf('/') + 1);
		T product = null;
		if(id != null){
			CrudDao<T> dao = getDAO();
			product = getGson().fromJson(req.getReader(), dao.getClazz());
			if(product != null){
				if(update) dao.updateResource(product);
				else dao.createResource(product);
			}
		}
		returnJSON(product, resp);
	}

	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String path = req.getPathInfo();
		String id = path.substring(path.indexOf('/') + 1);
		if(id != null){
			CrudDao<T> dao = getDAO();
			dao.deleteResource(id);
		}
		returnJSON(null, resp);
	}

}
